package com.chance.cc.crawler.development.scripts.tenxun.qqCarSerial;

import com.chance.cc.crawler.core.CrawlerRecordContext;
import com.chance.cc.crawler.core.downloader.HttpPage;
import com.chance.cc.crawler.core.pipeline.result.CrawlerData;
import com.chance.cc.crawler.core.record.CrawlerRequestRecord;
import com.chance.cc.crawler.core.script.crawler.CrawlerCommonScript;
import com.chance.cc.crawler.core.selector.Json;
import com.chance.cc.crawler.core.tags.CategoryTag;
import com.chance.cc.crawler.core.tags.crawler.CrawlerResultTags;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.chance.cc.crawler.core.CrawlerEnum.CrawlerDataType.article;
import static com.chance.cc.crawler.development.scripts.allfeild.AutoVMCommonField.*;

public class TencentCarScript extends CrawlerCommonScript {
    //private static final String START_URL = "https://auto.qq.com/car_public/index.shtml";
    private static final String START_URL = "https://auto.qq.com/car_public/index.shtml\\?serial_id=\\S*";
    private static final String START_DATA_URL = "https://api.ait.auto.qq.com/cardata/serial/all4oldpc";//首页数据来源
    private static final String DOMAIN = "tenxun";
    private static final String SITE = "carinfo";
    //车系详细正则
    private static final String CARDETAIL_REGEX = "https://auto.qq.com/car_serial/index.shtml\\?serial_id=\\S*";
    private static final String MODEL_REGEX = "https://api.ait.auto.qq.com/cardata/serial/modellist\\?\\S*";
    private static final Logger logger = LoggerFactory.getLogger(TencentCarScript.class);
    //格式化
    private static final String START_URL_FORMAT = "https://auto.qq.com/car_serial/index.shtml?serial_id=%s";

    //private static char[] letters = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
    @Override
    public String domain() {
        return DOMAIN;
    }

    @Override
    public void initUrlRegulars() {
        addUrlRegular(START_URL);
        addUrlRegular(START_DATA_URL);
        addUrlRegular(CARDETAIL_REGEX);
        addUrlRegular(MODEL_REGEX);
    }

    @Override
    public boolean crawlerCheck(CrawlerRequestRecord crawlerRequestRecord) {
        CategoryTag categoryTag = crawlerRequestRecord.tagsCreator().bizTags().getCategoryTag();
        String crawlerSite = categoryTag.getKVTagStrVal("site");
        return crawlerSite.equalsIgnoreCase(SITE);
    }

    @Override
    public void afterExecute(CrawlerRecordContext crawlerRecordContext) {

    }

    @Override
    public List<CrawlerRequestRecord> parseLinks(CrawlerRequestRecord crawlerRequestRecord, HttpPage httpPage) {
        List<CrawlerRequestRecord> parseLinks = new ArrayList<>();
        String parseUrl = httpPage.getRequest().getUrl();

//        if (parseUrl.matches(START_URL)) {
//            CrawlerRequestRecord startDataRecord = CrawlerRequestRecord.builder()
//                    .itemPageRequest(crawlerRequestRecord)
//                    .httpUrl(START_DATA_URL)
//                    .recordKey(START_DATA_URL)
//                    .releaseTime(System.currentTimeMillis())
//                    .copyBizTags()
//                    .needWashed(false)
//                    .build();
//            parseLinks.add(startDataRecord);
//        }
//        if (parseUrl.matches(START_DATA_URL))
//            parseDetails(crawlerRequestRecord, httpPage, parseLinks);
        if (parseUrl.matches(START_URL))
            parseArticle(crawlerRequestRecord, httpPage, parseLinks);
        return parseLinks;
    }

    public void parseDetails(CrawlerRequestRecord crawlerRequestRecord, HttpPage httpPage, List<CrawlerRequestRecord> parseLinks) {
        Json json = httpPage.getJson();
        Long nowTime = System.currentTimeMillis();
        List<String> list = json.jsonPath($_type + ".list").all();
        //list--> BrandList-->manList-->serialList-->serialID
        for (String li : list) {
            Json json_list = new Json(li);
            List<String> brand_list = json_list.jsonPath($_type+".BrandList").all();
            for (String bl : brand_list) {
                Json json_man = new Json(bl);
                List<String> man_list = json_man.jsonPath($_type + ".manList").all();
                for (String ml : man_list) {
                    Json json_serial = new Json(ml);
                    List<String> list_serial = json_serial.jsonPath($_type + ".serialList").all();
                    for (String sl : list_serial) {
                        Json json_end = new Json(sl);
                        String serial_id = json_end.jsonPath($_type + ".serialID").get();
                        String url = String.format(START_URL_FORMAT, serial_id);
                        CrawlerRequestRecord itemRecord = CrawlerRequestRecord.builder()
                                .itemPageRequest(crawlerRequestRecord)
                                .recordKey(url)
                                .httpUrl(url)
                                .releaseTime(nowTime)
                                .copyBizTags()
                                .needWashed(false)
                                .build();
                        parseLinks.add(itemRecord);
                    }
                }
            }
        }
    }
    public void parseArticle(CrawlerRequestRecord crawlerRequestRecord, HttpPage httpPage, List<CrawlerRequestRecord> parseLinks) {
        final String salt = "t*e&n^c%e%n#t@a(u*t&o";
        String articleUrl = httpPage.getRequest().getUrl();
        Object serial_id = getUrlParams(articleUrl).get("serial_id");
        Long nowTime = System.currentTimeMillis();
        Integer serialId = null;
        if (serial_id != null && (String) serial_id != "null") {
            serialId = Integer.valueOf((String) serial_id);//2527可能出现问题
            //_t=1634535100 @salt=t*e&n^c%e%n#t@a(u*t&o @serial_id=997 sha1算法加密
            String encryption = String.format("_t=%s@salt=%s@serial_id=%s", nowTime, salt, serialId);
            String sign = DigestUtils.sha1Hex(encryption);
            String modelUrl = String.format("https://api.ait.auto.qq.com/cardata/serial/modellist?serial_id=%s&_t=%s&sign=%s", serialId, nowTime, sign);
            CrawlerRequestRecord articleRecord = CrawlerRequestRecord.builder()
                    .itemPageRequest(crawlerRequestRecord)
                    .httpUrl(modelUrl)
                    .recordKey(modelUrl)
                    .releaseTime(nowTime)
                    .copyBizTags()
                    .resultLabelTag(article)
                    .build();
            parseLinks.add(articleRecord);
        }

    }

    @Override
    public List<CrawlerData> washPage(CrawlerRequestRecord crawlerRequestRecord, HttpPage httpPage) {
        List<CrawlerData> crawlerDataList = new ArrayList<>();
        CrawlerResultTags resultTags = crawlerRequestRecord.tagsCreator().resultTags();
        if (resultTags.hasDataType(article)) {
            crawlerDataList.addAll(washArticle(crawlerRequestRecord, httpPage));
        }
        return crawlerDataList;
    }

    public List<CrawlerData> washArticle(CrawlerRequestRecord crawlerRequestRecord, HttpPage httpPage) {
        List<CrawlerData> modelData = new ArrayList<>();
        Json json = httpPage.getJson();
        int zaishou_Size = json.jsonPath($_type + ".data.zaishou_list[*].models[*].id").all().size();
        int tingshou_Size = json.jsonPath($_type+".data.tingshou_list[*].models[*].id").all().size();
        Object serial_id = getUrlParams(httpPage.getRequest().getUrl()).get("serial_id");//车系id
        Integer serialId = null;
        String serial_name = json.jsonPath($_type+".data.name").get();//车系名
        String brand_name = json.jsonPath(($_type+".data.brand_name")).get();//品牌名
        String brand_id = json.jsonPath($_type+".data.brand_id").get();//品牌id
        if (serial_id != null)
            serialId = Integer.valueOf((String) serial_id);
        //在售数据
        for (int i = 0; i < zaishou_Size; i++) {
            String model_id = json.jsonPath($_type + ".data.zaishou_list[*].models["+i+"].id").get();
            String name = json.jsonPath($_type + ".data.zaishou_list[*].models[" + i + "].name").get();
            String model_zaishou_url = String.format("https://auto.qq.com/car_serial/modelscompare.shtml#/config?serial_id=%s&model_id=%s", serialId, model_id);
            CrawlerData crawlerData = CrawlerData.builder()
                    .data(crawlerRequestRecord, httpPage)
                    .dataId(StringUtils.joinWith("-", crawlerRequestRecord.getDomain(), article, model_id))
                    .releaseTime(System.currentTimeMillis())
                    .addContentKV(Tag_Is_sale,"1")//在售
                    .addContentKV(Field_Brand_id,brand_id)
                    .addContentKV(Field_Brand_name,brand_name)
                    .addContentKV(Field_Series_id,(String) serial_id)
                    .addContentKV(Field_Series_name,serial_name)
                    .addContentKV(Field_Model_name, name)
                    .addContentKV(Field_Model_url, model_zaishou_url)
                    .resultLabelTag(article)
                    .build();
            modelData.add(crawlerData);
        }
        //停售数据
       for (int i = 0; i < tingshou_Size; i++) {
            String model_id = json.jsonPath($_type + ".data.tingshou_list[*].models[*].id").get();
            String name = json.jsonPath($_type + ".data.tingshou_list[*].models[" + i + "].name").get();
            String model_zaishou_url = String.format("https://auto.qq.com/car_serial/modelscompare.shtml#/config?serial_id=%s&model_id=%s", serialId, model_id);
            CrawlerData crawlerData = CrawlerData.builder()
                    .data(crawlerRequestRecord, httpPage)
                    .dataId(StringUtils.joinWith("-", crawlerRequestRecord.getDomain(), article, model_id))
                    .parentId(StringUtils.joinWith("-", crawlerRequestRecord.getDomain(), article, serialId))
                    .releaseTime(System.currentTimeMillis())
                    .addContentKV(Tag_Is_sale,"0")//未售
                    .addContentKV(Field_Brand_id,brand_id)
                    .addContentKV(Field_Brand_name,brand_name)
                    .addContentKV(Field_Series_id,(String) serial_id)
                    .addContentKV(Field_Series_name,serial_name)
                    .addContentKV(Field_Model_name, name)
                    .addContentKV(Field_Model_url, model_zaishou_url)
                    .resultLabelTag(article)
                    .build();
            modelData.add(crawlerData);
        }
        return modelData;
    }

    //解析url的参数
    private Map<String, Object> getUrlParams(String url) {
        Map<String, Object> map = new HashMap<String, Object>(0);
        String param = url;
        if (url.contains("?")) {
            param = url.split("\\?")[1];
        }
        if (StringUtils.isBlank(param)) {
            return null;
        }
        String[] params = param.split("&");
        for (String s : params) {
            String[] p = s.split("=");
            if (p.length == 2) {
                map.put(p[0], p[1]);
            }
        }
        return map;
    }

}
